﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;
using Datos.Fabricas;
using Datos.Interfaces;
using Datos.Entidades;
using Datos.Entidades.FabricaEntidades;
using log4net;
namespace Datos.DAOSqlServer

{
    /// <summary>
    /// Clase DAO que permite el Acceso a los metodos de los usuario
    /// </summary>
    public class DAOSqlServerAccesoUsuario : IDAOAccesoUsuario
    {


        #region Logger
        private static readonly ILog log = LogManager.GetLogger(
        System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);





        #endregion 
        IDAOAccesoConexion bd = FabricaConexion.DAOSqlServerAccesoConexion();


        #region Constructor
        public DAOSqlServerAccesoUsuario()
        {
            log.Info("Conexion DAOSqlAccesoUsuario");
        }
        #endregion
        /// <summary>
        /// Inserta un nuevo usuario en la base de datos
        /// </summary>
        /// <param name="usuario">Usuario a insertar</param>
        /// <returns>Si la creación fue exitosa o no</returns>
        public bool InsertarUsuario(Entidad usuario)
        {
            SqlCommand command = new SqlCommand();
            try
            {
                bd.AbrirConexionBd();
                command.Connection = bd.ObjetoConexion();
                command.CommandType = System.Data.CommandType.StoredProcedure;
                command.CommandText = "[dbo].[INSUsuario]";
                command.CommandTimeout = 10;

                //command.Parameters.AddWithValue("@Id_Usuario", (usuario as Usuario).Id_Usuario);
                command.Parameters.AddWithValue("@Nombre", (usuario as Usuario).Nombre);
                command.Parameters.AddWithValue("@Apellido", (usuario as Usuario).Apellido);
                command.Parameters.AddWithValue("@Cedula", (usuario as Usuario).Cedula);
                command.Parameters.AddWithValue("@FK_Id_Rol", (usuario as Usuario).Fk_Id_Rol);
                command.Parameters.AddWithValue("@Telefono", (usuario as Usuario).Telefono);
                command.Parameters.AddWithValue("@Email", (usuario as Usuario).Email);
                command.Parameters.AddWithValue("@Clave", (usuario as Usuario).Clave);
                command.Parameters.AddWithValue("@Login", (usuario as Usuario).Login);
                command.Parameters.AddWithValue("@Estatus", (usuario as Usuario).Estatus);
                command.Parameters.AddWithValue("@ClaveCifrada", (usuario as Usuario).ClaveCifrada);


                SqlDataReader reader = command.ExecuteReader();
                log.Info("Se genero la consulta de Insertar usuario");
                reader.Close();
                bd.CerrarConexionBd();
                return true;
            }
            catch (SqlException)
            {
                log.Error("No se genero la consulta");
                bd.CerrarConexionBd();
                return false;
            }
            catch (Exception)
            {
                log.Error("Error en la aplicacion");
                bd.CerrarConexionBd();
                return false;
            }
        }

        /// <summary>
        /// Consulta Usuario por el Estatus
        /// </summary>
        /// <returns>Lista de usuarios, activos y inactivos  </returns>
        public List<Entidad> ConsultarUsuariosEstatus()
        {

            SqlCommand command = new SqlCommand();
            List<Entidad> listaUsuarios = new List<Entidad>();
            Entidad rol = FabricaEntidades.ObtenerRol();
            List<Rol> listaRol = new List<Rol>();
            try
            {

                bd.AbrirConexionBd();
                command.Connection = bd.ObjetoConexion();
                command.CommandType = System.Data.CommandType.StoredProcedure; //Tipo de comando que se va a ejecutar
                command.CommandText = "[dbo].[BUSUsuario]"; // Nombre del Procedimiento Almacenado en la Base de Datos
                command.CommandTimeout = 10;
                //command.Parameters.AddWithValue("@Estatus", Estatus);


                SqlDataReader reader = command.ExecuteReader();

                while (reader.Read())
                {
                    Entidad usuario = FabricaEntidades.ObtenerUsuario();

                    (usuario as Usuario).Id_Usuario = reader.GetInt32(0);
                    (usuario as Usuario).Nombre = reader["Nombre"].ToString();
                    (usuario as Usuario).Apellido = reader["Apellido"].ToString();
                    (usuario as Usuario).Cedula = reader.GetInt32(3);
                    (usuario as Usuario).Telefono = reader.GetInt64(4);
                    (usuario as Usuario).Email = reader["Email"].ToString();
                    (usuario as Usuario).Clave = reader["Clave"].ToString();
                    (usuario as Usuario).Login = reader["Login"].ToString();
                    (usuario as Usuario).Estatus = reader["Estatus"].ToString();
                    (rol as Rol).NombreRol = reader["Rol"].ToString();
                    (usuario as Usuario).Fk_Id_Rol = reader.GetInt32(10);
                    (rol as Rol).Id_Rol = reader.GetInt32(10);
                    listaRol.Add(rol as Rol);
                    //  (usuario as Usuario).Roles.Add(rol as Rol);
                    listaUsuarios.Add((usuario as Usuario));
                }
                log.Info("Se genero la consulta, ConsultarUsuarioEstatus " );
                reader.Close();
                bd.CerrarConexionBd();
                return listaUsuarios;


            }

            catch (SqlException)
            {
                log.Error("Error en la consulta, ConsultarUsuarioEstatus");
                bd.CerrarConexionBd();
                return null;
            }

            catch (Exception)
            {
                log.Error("Error en la aplicacion");
                bd.CerrarConexionBd();
                return null;
            }
        }
        /// <summary>
        /// Consultar un usuario por un Id dado
        /// </summary>
        /// <param name="id"> id del usuario a consultar</param>
        /// <returns>Un usuario </returns>
        public Entidad ConsultarUsuarioPorId(int id)
        {

            SqlCommand command = new SqlCommand();
            try
            {

                bd.AbrirConexionBd();
                command.Connection = bd.ObjetoConexion();
                command.CommandType = System.Data.CommandType.StoredProcedure; //Tipo de comando que se va a ejecutar
                command.CommandText = "[dbo].[BUSUsuarioID]"; // Nombre del Procedimiento Almacenado en la Base de Datos
                command.CommandTimeout = 10;

                command.Parameters.AddWithValue("@Id", id);

                SqlDataReader reader = command.ExecuteReader();
                Entidad usuario = FabricaEntidades.ObtenerUsuario();
                Entidad rol = FabricaEntidades.ObtenerRol();
                List<Rol> roles = new List<Rol>();
                while (reader.Read())
                {

                    (usuario as Usuario).Nombre = reader["Nombre"].ToString();
                    (usuario as Usuario).Apellido = reader["Apellido"].ToString();
                    (usuario as Usuario).Cedula = reader.GetInt32(2);
                    (usuario as Usuario).Telefono = reader.GetInt64(3);
                    (usuario as Usuario).Email = reader["Email"].ToString();
                    (usuario as Usuario).Clave = reader["Clave"].ToString();
                    (usuario as Usuario).Login = reader["Login"].ToString();
                    (usuario as Usuario).Estatus = reader["Estatus"].ToString();
                    (rol as Rol).NombreRol = reader["Rol"].ToString();
                    (usuario as Usuario).Fk_Id_Rol = reader.GetInt32(9);
                    (rol as Rol).Id_Rol = reader.GetInt32(9);
                    roles.Add((rol as Rol));
                    (usuario as Usuario).Roles = roles;
                    //listaRol.Add(rol as Rol);
                    (usuario as Usuario).Roles.Add(rol as Rol);
                    // listaUsuarios.Add((usuario as Usuario));
                }
                log.Info("Se genero ConsultarUsuarioPorId");
                reader.Close();
                bd.CerrarConexionBd();
                return usuario;


            }

            catch (SqlException)
            {
                log.Error("No se genero la consulta");
                bd.CerrarConexionBd();
                return null;
            }

            catch (Exception)
            {
                log.Error("Error en la aplicacion");
                bd.CerrarConexionBd();
                return null;
            }


        }
        /// <summary>
        /// Modifica los datos de un usuario
        /// </summary>
        /// <param name="usuario">usuario a modificar</param>
        /// <returns>si el ususario fue modificado o no</returns>
        public bool ModificarUsuario(Entidad usuario)
        {
            SqlCommand command = new SqlCommand();
            //   string modificar = "Modificacion";
            try
            {



                bd.AbrirConexionBd();
                command.Connection = bd.ObjetoConexion();
                command.CommandType = System.Data.CommandType.StoredProcedure; //Tipo de comando que se va a ejecutar
                command.CommandText = "[dbo].[UPDUsuario]"; // Nombre del Procedimiento Almacenado en la Base de Datos
                command.CommandTimeout = 10;
                command.Parameters.AddWithValue("@Id_Usuario", (usuario as Usuario).Id_Usuario);
                command.Parameters.AddWithValue("@Nombre", (usuario as Usuario).Nombre);
                command.Parameters.AddWithValue("@Apellido", (usuario as Usuario).Apellido);
                command.Parameters.AddWithValue("@Cedula", (usuario as Usuario).Cedula);
                command.Parameters.AddWithValue("@Telefono", (usuario as Usuario).Telefono);
                command.Parameters.AddWithValue("@Email", (usuario as Usuario).Email);
                command.Parameters.AddWithValue("@Clave", (usuario as Usuario).Clave);
                command.Parameters.AddWithValue("@Login", (usuario as Usuario).Login);
                command.Parameters.AddWithValue("@Estatus", (usuario as Usuario).Estatus);


                SqlDataReader reader = command.ExecuteReader();
                log.Info("Se genero la consulta de modificarUsuario");
                reader.Close();
                bd.CerrarConexionBd();
                return true;


            }

            catch (SqlException)
            {
                log.Error("no se ejecuto la consulta");
                bd.CerrarConexionBd();
                return false;
            }

            catch (TimeoutException)
            {
                log.Error("error en tiempo de ejecucion");
                bd.CerrarConexionBd();
                return false;
            }

            catch (Exception)
            {
                log.Error("error en la aplicacion");
                bd.CerrarConexionBd();
                return false;
            }
        }
        /// <summary>
        /// Consulta los datos de un usuario segun su login y clave
        /// </summary>
        /// <param name="usuario">recibe el login y la clave</param>
        /// <returns>los datos del usuario si existe </returns>
        public Entidad ConsultarUsuarioLogin(Entidad usuario)
        {

            SqlCommand command = new SqlCommand();
            try
            {

                bd.AbrirConexionBd();
                command.Connection = bd.ObjetoConexion();
                command.CommandType = System.Data.CommandType.StoredProcedure; //Tipo de comando que se va a ejecutar
                command.CommandText = "[dbo].[BUSUsuarioLogin]"; // Nombre del Procedimiento Almacenado en la Base de Datos
                command.CommandTimeout = 10;

                command.Parameters.AddWithValue("@ClaveEncriptada", (usuario as Usuario).ClaveCifrada);
                command.Parameters.AddWithValue("@Login", (usuario as Usuario).Login);

                SqlDataReader reader = command.ExecuteReader();
               
                Entidad rol = FabricaEntidades.ObtenerRol();
                List<Rol> roles = new List<Rol>();

                while (reader.Read())
                {
                     
                    (usuario as Usuario).Id_Usuario = reader.GetInt32(0);
                    (usuario as Usuario).Nombre = reader["Nombre"].ToString();
                    (usuario as Usuario).Apellido = reader["Apellido"].ToString();
                    (usuario as Usuario).Cedula = reader.GetInt32(3);
                    (usuario as Usuario).Telefono = reader.GetInt64(4);
                    (usuario as Usuario).Email = reader["Email"].ToString();
                   
                    (usuario as Usuario).Estatus = reader["Estatus"].ToString();
                    (rol as Rol).NombreRol = reader["Rol"].ToString();
                    (usuario as Usuario).Fk_Id_Rol = reader.GetInt32(8);
                    (rol as Rol).Id_Rol = reader.GetInt32(8);
                    roles.Add((rol as Rol));
                    (usuario as Usuario).Roles = roles;
                    //listaRol.Add(rol as Rol);
                    (usuario as Usuario).Roles.Add(rol as Rol);
                    // listaUsuarios.Add((usuario as Usuario));
                }
                log.Info("Se genero la consulta ConsultarUsuarioLogin");
                reader.Close();
                bd.CerrarConexionBd();
                return usuario;


            }

            catch (SqlException)
            {
                log.Error("Error en la consulta");
                bd.CerrarConexionBd();
                return null;
            }

            catch (Exception)
            {
                log.Error("Error en la aplicacion");
                bd.CerrarConexionBd();
                return null;
            }



        }
        /// <summary>
        /// Consulta la posicion del ultimo usuario agregado
        /// </summary>
        /// <returns>ID del usuario</returns>
        public Entidad ConsultarUltimoID()
        {

            SqlCommand command = new SqlCommand();
           
            try
            {

                bd.AbrirConexionBd();
                command.Connection = bd.ObjetoConexion();
                command.CommandType = System.Data.CommandType.StoredProcedure; //Tipo de comando que se va a ejecutar
                command.CommandText = "[dbo].[SELMaxID]"; // Nombre del Procedimiento Almacenado en la Base de Datos
                command.CommandTimeout = 10;
                //command.Parameters.AddWithValue("@Estatus", Estatus);


                SqlDataReader reader = command.ExecuteReader();
                Entidad usuario = FabricaEntidades.ObtenerUsuario();

                while (reader.Read())
                {
                   

                    (usuario as Usuario).Id_Usuario = reader.GetInt32(0);
                    (usuario as Usuario).Login = reader["Login"].ToString();
                    (usuario as Usuario).Clave = reader["Clave"].ToString();
                    
                   
                   
                }
                log.Info("Se genero la consulta ");
                reader.Close();
                bd.CerrarConexionBd();
                return usuario;


            }

            catch (SqlException)
            {
                log.Error("Error en la consulta");
                bd.CerrarConexionBd();
                return null;
            }

            catch (Exception)
            {
                log.Error("Error en la aplicacion");
                bd.CerrarConexionBd();
                return null;
            }
        
        }

       /// <summary>
       /// Consulta un usuario dado un Email
       /// </summary>
       /// <param name="email"></param>
       /// <returns>La cedula del usuario </returns>
        public Entidad ConsultarUsuarioPorEmail(String email)
        {

            SqlCommand command = new SqlCommand();
            try
            {

                bd.AbrirConexionBd();
                command.Connection = bd.ObjetoConexion();
                command.CommandType = System.Data.CommandType.StoredProcedure; //Tipo de comando que se va a ejecutar
                command.CommandText = "[dbo].[BUSUsuarioEmail]"; // Nombre del Procedimiento Almacenado en la Base de Datos
                command.CommandTimeout = 10;

                command.Parameters.AddWithValue("@Email", email);

                SqlDataReader reader = command.ExecuteReader();
                Entidad usuario = FabricaEntidades.ObtenerUsuario();
                Entidad rol = FabricaEntidades.ObtenerRol();
                List<Rol> roles = new List<Rol>();
                while (reader.Read())
                {

                    (usuario as Usuario).Cedula = reader.GetInt32(0);
                    
                   
                }
                log.Info("Se genero ConsultarUsuarioPorEmail");
                reader.Close();
                bd.CerrarConexionBd();
                return usuario;


            }

            catch (SqlException)
            {
                log.Error("No se genero la consulta");
                bd.CerrarConexionBd();
                return null;
            }

            catch (Exception)
            {
                log.Error("Error en la aplicacion");
                bd.CerrarConexionBd();
                return null;
            }


        }
    }
}
